package com.upcode.weighing.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.upcode.weighing.feignservice.BaseResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Slf4j
public class RestTemplateUtil {

//    public static final String URL ="http://localhost:9097/";
//    public static final String URL ="http://192.168.10.2:7110/";

    @Bean
    @LoadBalanced
    public static RestTemplate getInstance(String charset) {
        RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
        for (HttpMessageConverter<?> httpMessageConverter : list) {
            if(httpMessageConverter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName(charset));
            }
        }
        return restTemplate;
    }

    public static BaseResult<T> postForEagleData(String url, T obj) throws Exception {

        log.info("======postForEntitySendMQ==========URL==" + url);
        RestTemplate restTemplate = getInstance("utf-8");
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<Object> requestEntity = new HttpEntity<>(obj, requestHeaders);
//        ResponseEntity<BaseResult> baseResult = restTemplate.postForEntity(url, requestEntity, BaseResult.class);
        BaseResult<T> baseResult = restTemplate.exchange(url,
                HttpMethod.POST,requestEntity,
                new ParameterizedTypeReference<BaseResult<T>>() {}).getBody();
        log.info("======baseResult.getData().getClass()=====" + baseResult.getData().getClass());
        log.info("======RestTemplateUtil=====" + JSONObject.toJSONString(baseResult));
        return baseResult;
    }


    public static <T> T postForOBJ(String url, Object obj,ParameterizedTypeReference<T> responseType) throws Exception {

        log.info("======postForUrl==========URL==" + url);
        RestTemplate restTemplate = getInstance("utf-8");
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<Object> requestEntity = new HttpEntity<>(obj, requestHeaders);
        T baseResult = restTemplate.exchange(url,
                HttpMethod.POST,requestEntity,
                responseType).getBody();
        log.info("post 调用成功,调用url:[{}],调用返回数据:[{}]" ,url, JSONObject.toJSONString(baseResult));
        return baseResult;
    }

    /**
     * 解决信联发送请求报出302的问题,允许客户端跟随服务端重定向而跳转
     * @param url
     * @param obj
     * @param responseType
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T postForXinlian(String url, Object obj,ParameterizedTypeReference<T> responseType) throws Exception {
        log.info("======postForXinlian==========URL==" + url);
        final RestTemplate restTemplate = new RestTemplate();
        final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        final HttpClient httpClient = HttpClientBuilder.create()
                .setRedirectStrategy(new LaxRedirectStrategy())
                .build();
        factory.setHttpClient(httpClient);
        restTemplate.setRequestFactory(factory);
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<Object> requestEntity = new HttpEntity<>(obj, requestHeaders);
        T baseResult = restTemplate.exchange(url,
                HttpMethod.POST,requestEntity,
                responseType).getBody();
        log.info("post 调用成功,调用url:[{}],调用返回数据:[{}]" ,url, JSONObject.toJSONString(baseResult));
        return baseResult;
    }
    public static <T> T postForOBJ(String url,String token, Object obj,ParameterizedTypeReference<T> responseType) throws Exception {
        log.info("======postForSendMQ==========URL==" + url);
        RestTemplate restTemplate = getInstance("utf-8");
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        //requestHeaders.add("Accept", MediaType.APPLICATION_JSON.toString());
        requestHeaders.add("Authorization", "bearer " + token);
        HttpEntity<Object> requestEntity = new HttpEntity<>(obj, requestHeaders);
        T baseResult = restTemplate.exchange(url,
                HttpMethod.POST,requestEntity,
                responseType).getBody();
        log.info("======RestTemplateUtil=====" + JSONObject.toJSONString(baseResult));
        return baseResult;
    }

    public static <T> T getForOBJ(String url, Object obj,ParameterizedTypeReference<T> responseType) throws Exception {

        log.info("======postForSendMQ==========URL==" + url);
        RestTemplate restTemplate = getInstance("utf-8");
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<Object> requestEntity = new HttpEntity<>(obj, requestHeaders);
        T baseResult = restTemplate.exchange(url,
                HttpMethod.GET,requestEntity,
                responseType).getBody();
        log.info("======RestTemplateUtil=====" + JSONObject.toJSONString(baseResult));
        return baseResult;
    }

    public static String getToken(String uri) {
        RestTemplate restTemplate = getInstance("utf-8");
        RequestEntity requestEntity = null;
        try {
            requestEntity = RequestEntity
                    .post(new URI(uri))
                    .build();
        } catch (URISyntaxException e) {
            e.printStackTrace();
            return null;
        }
        ResponseEntity responseEntity = restTemplate.exchange(requestEntity, String.class);
        log.info("status code:" + responseEntity.getStatusCode());
        JSONObject json = JSON.parseObject(responseEntity.getBody().toString());
        log.info(responseEntity.getBody().toString());
        return json.getString("access_token");
    }
    
    public static JSONObject getToken2(String uri) {
        RestTemplate restTemplate = getInstance("utf-8");
        RequestEntity requestEntity = null;
        try {
            requestEntity = RequestEntity
                    .post(new URI(uri))
                    .build();
        } catch (URISyntaxException e) {
            e.printStackTrace();
            return null;
        }
        ResponseEntity responseEntity = restTemplate.exchange(requestEntity, String.class);
        log.debug(String.format("获取token返回值为[%s]",JSON.toJSONString(responseEntity)));
        log.info("status code:" + responseEntity.getStatusCode());
        JSONObject json = JSON.parseObject(responseEntity.getBody().toString());
        log.info(responseEntity.getBody().toString());
        return json;
    }
    

    public static  <T> T   addTokenAndPost(String token, String requestUri, Object param, ParameterizedTypeReference<T> responseType ) {
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        requestHeaders.add(HttpHeaders.AUTHORIZATION, "bearer   " + token);
        HttpEntity<Object> requestEntity = new HttpEntity<>(param, requestHeaders);
        RestTemplate restTemplate = getInstance("utf-8");
        T body = restTemplate.exchange(requestUri, HttpMethod.POST, requestEntity, responseType).getBody();
        log.info("======RestTemplateUtil addTokenAndPost =====" + JSONObject.toJSONString(body));
        return  body;

    }

    public static ResponseEntity<byte[]> getFileComplain(String url){
        RestTemplate restTemplate = getInstance("utf-8");
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<Resource> httpEntity = new HttpEntity<Resource>(headers);
        ResponseEntity<byte[]> response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, byte[].class);
        return response;
    }

    public static Map postForFileComplain(String url, List<String> filePaths) throws Exception {
        RestTemplate restTemplate = getInstance("utf-8");
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);
        //设置请求体，注意是LinkedMultiValueMap
        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add("act","upload_files");
        for(String file : filePaths){
            //设置请求体，注意是LinkedMultiValueMap
            FileSystemResource fileSystemResource = new FileSystemResource(file);
            form.add("file[]", fileSystemResource);
        }
        Map<String, Object> result = new HashMap<>();
        //用HttpEntity封装整个请求报文
        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(form, headers);
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, formEntity, String.class);
        if(null == responseEntity || StringUtils.isBlank(responseEntity.getBody())){
            return null;
        }
        String s = responseEntity.getBody();
        log.debug(String.format("请求96200文件上传返回值为[%s]",s));
        JSONObject obj = JSON.parseObject(s);
        //循环转换
        Iterator it =obj.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
            result.put(entry.getKey(), entry.getValue());
        }
        for(String file : filePaths){
            new File(file).delete();
            log.debug(String.format("文件[%s]删除成功",file));
        }
        return result;

    }

}
